package com.jymj.utils.FileUtile;

import com.jymj.utils.RRException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

/**
 * @author Lzh
 * @date 2021/7/16 15:20
 */
@Slf4j
public class FileUtile {
    private static Set<String> typeSet = new HashSet<>();

    static {
        typeSet.add(".exe");
        typeSet.add(".bat");
        typeSet.add(".sh");
        //....
    }


    public FileUploadEntity initFileUtile(String pathHead) {
        FileUploadEntity uploadEntity = new FileUploadEntity(pathHead);
        return uploadEntity;
    }

    public static FileUploadEntity fileUpload(MultipartFile file, FileUploadEntity fileUploadEntity) {
        //验证信息
        if (file == null) {
            log.error("无文件上传");
            throw new RRException("无文件上传");
        }
        if (fileUploadEntity == null || fileUploadEntity.getPathHead().isEmpty() || fileUploadEntity.getUrlHead().isEmpty()) {
            log.error("文件头信息错误（无法获取配置内文件头信息 或信息不存在）");
            throw new RRException("文件头信息错误（无法获取配置内文件头信息 或信息不存在）");
        }

        //获取文件的全名
        String fileName = file.getOriginalFilename();
        fileName = fileName.toLowerCase();//将所有的字符转化为小写
        fileUploadEntity.setFileName(fileName);
        //禁止上传exe bat sh脚本文件
        int index = fileName.lastIndexOf(".");
        String fileType = fileName.substring(index);
        if (typeSet.contains(fileType)) {
            log.warn("上传文件为可执行文件，可能存在恶意程序，禁止上传");
            throw new RRException("禁止上传可执行文件");
        }
        if (file.getSize() == 0) {
            log.error("禁止上传大小为0kb的文件");
            throw new RRException("上传的文件为0kb，请检查是否上传正确");
        }
        //确定上传文件的根目录 如果不存在 创建目录
        File sourcePath = new File((fileUploadEntity.getPathHead() + File.separator + fileUploadEntity.getUploadType()));
        if (!sourcePath.exists()) {
            log.info("文件不存在，创建新文件");
            sourcePath.mkdirs();
        }
        //采用分目录存储的方式  a.jpg
        //分目录存储方式1 hash方式 ACBBCDD
        //分目录存储方式2 时间方式存储 yyyy/MM/dd
        String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        File toPath = new File(sourcePath.getPath() + dateDir);
        if (!toPath.exists()) {
            log.info("文件不存在，创建新文件");
            toPath.mkdirs();
        }
        //3.2 准备文件存储的目录
        //实现文件上传
        //动态拼接文件名称   uuid.后缀  f3aa1378-ece6-11ea-98c9-00d861eaf238
        String uuid =
                UUID.randomUUID().toString().replace("-", "");
        String realFileName = uuid + fileType;//重新定义上传文件的名称防止文件上传到文件夹出现重复文件
        //准备文件上传的全路径  磁盘路径地址+文件名称
        File upLoadFile = new File(sourcePath + File.separator + dateDir + realFileName);
        //上传文件
        log.info(upLoadFile.getPath());
        try {
            file.transferTo(upLoadFile);
        } catch (IOException e) {
            e.printStackTrace();
            log.error("文件上传失败，服务器空间可能不足");
            throw new RRException("文件上传失败");
        }
        fileUploadEntity.setDataUrl(dateDir + realFileName)
                .setDataPath(fileUploadEntity.getUploadType() + dateDir + realFileName);

        return fileUploadEntity;
    }


    public static void fileDelete(String path, FileUploadEntity fileUploadEntity) {
        File file = new File(fileUploadEntity.getPath() + File.separator + path);
        if (file.exists()){
            file.delete();
        }
        log.info("删除文件的路径为：{}", fileUploadEntity.getPath() + File.separator + path);
    }
}
